//
//  DMLifecycleDelegateRegistry.m
//  DualMediationSDK
//
//  统一代理注册中心实现
//

#import "DMLifecycleDelegateRegistry.h"

#pragma mark - 代理包装器

/**
 * 代理包装器，用于存储代理和优先级信息
 */
@interface DMDelegateWrapper : NSObject
@property (nonatomic, weak) id delegate;
@property (nonatomic, assign) NSInteger priority;
@property (nonatomic, strong) NSString *identifier;

+ (instancetype)wrapperWithDelegate:(id)delegate priority:(NSInteger)priority;
+ (instancetype)wrapperWithDelegate:(id)delegate priority:(NSInteger)priority identifier:(NSString *)identifier;
@end

@implementation DMDelegateWrapper

+ (instancetype)wrapperWithDelegate:(id)delegate priority:(NSInteger)priority {
    return [self wrapperWithDelegate:delegate priority:priority identifier:nil];
}

+ (instancetype)wrapperWithDelegate:(id)delegate priority:(NSInteger)priority identifier:(NSString *)identifier {
    DMDelegateWrapper *wrapper = [[DMDelegateWrapper alloc] init];
    wrapper.delegate = delegate;
    wrapper.priority = priority;
    wrapper.identifier = identifier;
    return wrapper;
}

@end

#pragma mark - 统一代理注册中心实现

@interface DMLifecycleDelegateRegistry ()

// 生命周期监听器存储
@property (nonatomic, strong) NSMutableArray<DMDelegateWrapper *> *lifecycleDelegateWrappers;
@property (nonatomic, strong) dispatch_queue_t lifecycleDelegateQueue;

// SDK回调代理存储
@property (nonatomic, strong) NSHashTable<id<DMSDKLifecycleDelegate>> *sdkCallbackDelegates;
@property (nonatomic, strong) dispatch_queue_t sdkCallbackQueue;

// Facebook回调代理存储
@property (nonatomic, strong) NSHashTable<id<DMFacebookCallbackDelegate>> *facebookDelegates;
@property (nonatomic, strong) dispatch_queue_t facebookQueue;

// 广告代理存储
@property (nonatomic, strong) NSMutableArray<DMDelegateWrapper *> *adDelegateWrappers;
@property (nonatomic, strong) dispatch_queue_t adDelegateQueue;

// 扩展存储
@property (nonatomic, strong) NSMutableDictionary<NSString *, DMDelegateWrapper *> *extensionWrappers;
@property (nonatomic, strong) dispatch_queue_t extensionQueue;

@end

@implementation DMLifecycleDelegateRegistry

static DMLifecycleDelegateRegistry *_sharedRegistry = nil;
static dispatch_once_t onceToken;

#pragma mark - 单例实现

+ (instancetype)sharedRegistry {
    dispatch_once(&onceToken, ^{
        _sharedRegistry = [[self alloc] init];
    });
    return _sharedRegistry;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        [self setupQueuesAndStorage];
    }
    return self;
}

- (void)setupQueuesAndStorage {
    // 创建串行队列确保线程安全
    _lifecycleDelegateQueue = dispatch_queue_create("com.dualmediationsdk.lifecycle.delegate", DISPATCH_QUEUE_SERIAL);
    _sdkCallbackQueue = dispatch_queue_create("com.dualmediationsdk.sdk.callback", DISPATCH_QUEUE_SERIAL);
    _facebookQueue = dispatch_queue_create("com.dualmediationsdk.facebook.callback", DISPATCH_QUEUE_SERIAL);
    _adDelegateQueue = dispatch_queue_create("com.dualmediationsdk.ad.delegate", DISPATCH_QUEUE_SERIAL);
    _extensionQueue = dispatch_queue_create("com.dualmediationsdk.extension", DISPATCH_QUEUE_SERIAL);
    
    // 初始化存储容器
    _lifecycleDelegateWrappers = [NSMutableArray array];
    _sdkCallbackDelegates = [NSHashTable weakObjectsHashTable];
    _facebookDelegates = [NSHashTable weakObjectsHashTable];
    _adDelegateWrappers = [NSMutableArray array];
    _extensionWrappers = [NSMutableDictionary dictionary];
}

#pragma mark - 生命周期代理注册

- (void)registerLifecycleDelegate:(id<DMLifecycleEventListener>)delegate {
    [self registerLifecycleDelegate:delegate withPriority:DMLifecycleDelegatePriorityNormal];
}

- (void)registerLifecycleDelegate:(id<DMLifecycleEventListener>)delegate withPriority:(NSInteger)priority {
    if (!delegate) {
        return;
    }
    
    dispatch_async(self.lifecycleDelegateQueue, ^{
        // 检查是否已经注册
        for (DMDelegateWrapper *wrapper in self.lifecycleDelegateWrappers) {
            if (wrapper.delegate == delegate) {
                wrapper.priority = priority; // 更新优先级
                [self sortLifecycleDelegates];
                return;
            }
        }
        
        // 添加新的代理
        DMDelegateWrapper *wrapper = [DMDelegateWrapper wrapperWithDelegate:delegate priority:priority];
        [self.lifecycleDelegateWrappers addObject:wrapper];
        [self sortLifecycleDelegates];
    });
}

- (void)unregisterLifecycleDelegate:(id<DMLifecycleEventListener>)delegate {
    if (!delegate) {
        return;
    }
    
    dispatch_async(self.lifecycleDelegateQueue, ^{
        NSMutableArray *toRemove = [NSMutableArray array];
        for (DMDelegateWrapper *wrapper in self.lifecycleDelegateWrappers) {
            if (wrapper.delegate == delegate || wrapper.delegate == nil) {
                [toRemove addObject:wrapper];
            }
        }
        [self.lifecycleDelegateWrappers removeObjectsInArray:toRemove];
    });
}

- (void)sortLifecycleDelegates {
    [self.lifecycleDelegateWrappers sortUsingComparator:^NSComparisonResult(DMDelegateWrapper *obj1, DMDelegateWrapper *obj2) {
        if (obj1.priority < obj2.priority) {
            return NSOrderedAscending;
        } else if (obj1.priority > obj2.priority) {
            return NSOrderedDescending;
        }
        return NSOrderedSame;
    }];
}

#pragma mark - SDK回调代理注册

- (void)registerSDKDelegate:(id<DMSDKLifecycleDelegate>)delegate {
    [self registerSDKCallbackDelegate:delegate];
}

- (void)registerSDKCallbackDelegate:(id<DMSDKLifecycleDelegate>)delegate {
    if (!delegate) {
        return;
    }
    
    dispatch_async(self.sdkCallbackQueue, ^{
        [self.sdkCallbackDelegates addObject:delegate];
    });
}

- (void)unregisterSDKCallbackDelegate:(id<DMSDKLifecycleDelegate>)delegate {
    if (!delegate) {
        return;
    }
    
    dispatch_async(self.sdkCallbackQueue, ^{
        [self.sdkCallbackDelegates removeObject:delegate];
    });
}

#pragma mark - Facebook代理注册

- (void)registerFacebookDelegate:(id<DMFacebookCallbackDelegate>)delegate {
    if (!delegate) {
        return;
    }
    
    dispatch_async(self.facebookQueue, ^{
        [self.facebookDelegates addObject:delegate];
    });
}

- (void)unregisterFacebookDelegate:(id<DMFacebookCallbackDelegate>)delegate {
    if (!delegate) {
        return;
    }
    
    dispatch_async(self.facebookQueue, ^{
        [self.facebookDelegates removeObject:delegate];
    });
}

#pragma mark - 广告代理注册

- (void)registerAdDelegate:(id<DMAdDelegate>)delegate {
    [self registerAdDelegate:delegate withPriority:DMLifecycleDelegatePriorityNormal];
}

- (void)registerAdDelegate:(id<DMAdDelegate>)delegate withPriority:(NSInteger)priority {
    if (!delegate) {
        return;
    }
    
    dispatch_async(self.adDelegateQueue, ^{
        // 检查是否已经注册
        for (DMDelegateWrapper *wrapper in self.adDelegateWrappers) {
            if (wrapper.delegate == delegate) {
                wrapper.priority = priority; // 更新优先级
                [self sortAdDelegates];
                return;
            }
        }
        
        // 添加新的代理
        DMDelegateWrapper *wrapper = [DMDelegateWrapper wrapperWithDelegate:delegate priority:priority];
        [self.adDelegateWrappers addObject:wrapper];
        [self sortAdDelegates];
    });
}

- (void)unregisterAdDelegate:(id<DMAdDelegate>)delegate {
    if (!delegate) {
        return;
    }
    
    dispatch_async(self.adDelegateQueue, ^{
        NSMutableArray *toRemove = [NSMutableArray array];
        for (DMDelegateWrapper *wrapper in self.adDelegateWrappers) {
            if (wrapper.delegate == delegate || wrapper.delegate == nil) {
                [toRemove addObject:wrapper];
            }
        }
        [self.adDelegateWrappers removeObjectsInArray:toRemove];
    });
}

- (void)sortAdDelegates {
    [self.adDelegateWrappers sortUsingComparator:^NSComparisonResult(DMDelegateWrapper *obj1, DMDelegateWrapper *obj2) {
        if (obj1.priority < obj2.priority) {
            return NSOrderedAscending;
        } else if (obj1.priority > obj2.priority) {
            return NSOrderedDescending;
        }
        return NSOrderedSame;
    }];
}

#pragma mark - 扩展代理注册

- (void)registerLifecycleExtension:(id<DMLifecycleExtension>)extension {
    if (!extension || !extension.extensionIdentifier) {
        return;
    }
    
    dispatch_async(self.extensionQueue, ^{
        NSInteger priority = DMLifecycleDelegatePriorityNormal;
        if ([extension respondsToSelector:@selector(extensionPriority)]) {
            priority = [extension extensionPriority];
        }
        
        DMDelegateWrapper *wrapper = [DMDelegateWrapper wrapperWithDelegate:extension 
                                                                    priority:priority 
                                                                  identifier:extension.extensionIdentifier];
        self.extensionWrappers[extension.extensionIdentifier] = wrapper;
    });
}

- (void)unregisterLifecycleExtension:(NSString *)identifier {
    if (!identifier) {
        return;
    }
    
    dispatch_async(self.extensionQueue, ^{
        [self.extensionWrappers removeObjectForKey:identifier];
    });
}

- (nullable id<DMLifecycleExtension>)getLifecycleExtension:(NSString *)identifier {
    if (!identifier) {
        return nil;
    }
    
    __block id<DMLifecycleExtension> extension = nil;
    dispatch_sync(self.extensionQueue, ^{
        DMDelegateWrapper *wrapper = self.extensionWrappers[identifier];
        extension = wrapper.delegate;
    });
    
    return extension;
}

#pragma mark - 代理查询

- (NSArray<id<DMLifecycleEventListener>> *)getAllLifecycleDelegates {
    __block NSArray<id<DMLifecycleEventListener>> *delegates = nil;
    dispatch_sync(self.lifecycleDelegateQueue, ^{
        NSMutableArray *result = [NSMutableArray array];
        for (DMDelegateWrapper *wrapper in self.lifecycleDelegateWrappers) {
            if (wrapper.delegate) {
                [result addObject:wrapper.delegate];
            }
        }
        delegates = [result copy];
    });
    return delegates;
}

- (NSArray<id<DMLifecycleEventListener>> *)getLifecycleDelegatesWithPriority:(NSInteger)priority {
    __block NSArray<id<DMLifecycleEventListener>> *delegates = nil;
    dispatch_sync(self.lifecycleDelegateQueue, ^{
        NSMutableArray *result = [NSMutableArray array];
        for (DMDelegateWrapper *wrapper in self.lifecycleDelegateWrappers) {
            if (wrapper.delegate && wrapper.priority == priority) {
                [result addObject:wrapper.delegate];
            }
        }
        delegates = [result copy];
    });
    return delegates;
}

- (NSArray<id<DMSDKLifecycleDelegate>> *)getAllSDKCallbackDelegates {
    __block NSArray<id<DMSDKLifecycleDelegate>> *delegates = nil;
    dispatch_sync(self.sdkCallbackQueue, ^{
        delegates = [self.sdkCallbackDelegates allObjects];
    });
    return delegates;
}

- (NSArray<id<DMFacebookCallbackDelegate>> *)getAllFacebookDelegates {
    __block NSArray<id<DMFacebookCallbackDelegate>> *delegates = nil;
    dispatch_sync(self.facebookQueue, ^{
        delegates = [self.facebookDelegates allObjects];
    });
    return delegates;
}

- (NSArray<id<DMAdDelegate>> *)getAllAdDelegates {
    __block NSArray<id<DMAdDelegate>> *delegates = nil;
    dispatch_sync(self.adDelegateQueue, ^{
        NSMutableArray *result = [NSMutableArray array];
        for (DMDelegateWrapper *wrapper in self.adDelegateWrappers) {
            if (wrapper.delegate) {
                [result addObject:wrapper.delegate];
            }
        }
        delegates = [result copy];
    });
    return delegates;
}

- (NSArray<id<DMAdDelegate>> *)getAdDelegatesWithPriority:(NSInteger)priority {
    __block NSArray<id<DMAdDelegate>> *delegates = nil;
    dispatch_sync(self.adDelegateQueue, ^{
        NSMutableArray *result = [NSMutableArray array];
        for (DMDelegateWrapper *wrapper in self.adDelegateWrappers) {
            if (wrapper.delegate && wrapper.priority == priority) {
                [result addObject:wrapper.delegate];
            }
        }
        delegates = [result copy];
    });
    return delegates;
}

- (NSArray<id<DMLifecycleExtension>> *)getAllLifecycleExtensions {
    __block NSArray<id<DMLifecycleExtension>> *extensions = nil;
    dispatch_sync(self.extensionQueue, ^{
        NSMutableArray *result = [NSMutableArray array];
        NSArray *sortedWrappers = [self.extensionWrappers.allValues sortedArrayUsingComparator:^NSComparisonResult(DMDelegateWrapper *obj1, DMDelegateWrapper *obj2) {
            if (obj1.priority < obj2.priority) {
                return NSOrderedAscending;
            } else if (obj1.priority > obj2.priority) {
                return NSOrderedDescending;
            }
            return NSOrderedSame;
        }];
        
        for (DMDelegateWrapper *wrapper in sortedWrappers) {
            if (wrapper.delegate) {
                [result addObject:wrapper.delegate];
            }
        }
        extensions = [result copy];
    });
    return extensions;
}

#pragma mark - 代理管理

- (void)removeAllDelegates {
    [self removeAllLifecycleDelegates];
    [self removeAllSDKCallbackDelegates];
    [self removeAllFacebookDelegates];
    [self removeAllAdDelegates];
    [self removeAllLifecycleExtensions];
}

- (void)removeAllLifecycleDelegates {
    dispatch_async(self.lifecycleDelegateQueue, ^{
        [self.lifecycleDelegateWrappers removeAllObjects];
    });
}

- (void)removeAllSDKCallbackDelegates {
    dispatch_async(self.sdkCallbackQueue, ^{
        [self.sdkCallbackDelegates removeAllObjects];
    });
}

- (void)removeAllFacebookDelegates {
    dispatch_async(self.facebookQueue, ^{
        [self.facebookDelegates removeAllObjects];
    });
}

- (void)removeAllAdDelegates {
    dispatch_async(self.adDelegateQueue, ^{
        [self.adDelegateWrappers removeAllObjects];
    });
}

- (void)removeAllLifecycleExtensions {
    dispatch_async(self.extensionQueue, ^{
        [self.extensionWrappers removeAllObjects];
    });
}

#pragma mark - 统计信息

- (NSDictionary *)getDelegateStatistics {
    return @{
        @"lifecycleDelegateCount": @([self getLifecycleDelegateCount]),
        @"sdkCallbackDelegateCount": @([self getSDKCallbackDelegateCount]),
        @"facebookDelegateCount": @([self getFacebookDelegateCount]),
        @"adDelegateCount": @([self getAdDelegateCount]),
        @"lifecycleExtensionCount": @([self getLifecycleExtensionCount])
    };
}

- (NSUInteger)getLifecycleDelegateCount {
    __block NSUInteger count = 0;
    dispatch_sync(self.lifecycleDelegateQueue, ^{
        count = self.lifecycleDelegateWrappers.count;
    });
    return count;
}

- (NSUInteger)getSDKCallbackDelegateCount {
    __block NSUInteger count = 0;
    dispatch_sync(self.sdkCallbackQueue, ^{
        count = self.sdkCallbackDelegates.count;
    });
    return count;
}

- (NSUInteger)getFacebookDelegateCount {
    __block NSUInteger count = 0;
    dispatch_sync(self.facebookQueue, ^{
        count = self.facebookDelegates.count;
    });
    return count;
}

- (NSUInteger)getAdDelegateCount {
    __block NSUInteger count = 0;
    dispatch_sync(self.adDelegateQueue, ^{
        count = self.adDelegateWrappers.count;
    });
    return count;
}

- (NSUInteger)getLifecycleExtensionCount {
    __block NSUInteger count = 0;
    dispatch_sync(self.extensionQueue, ^{
        count = self.extensionWrappers.count;
    });
    return count;
}

@end